package com.yhb.third.leshua;

import com.yhb.dao.MPosMapper;
import com.yhb.model.PosBound;
import com.yhb.model.User;
import com.yhb.service.MPosService;
import com.yhb.service.UserService;
import com.yhb.third.leshua.dao.LeshuaExecutionFlowMapper;
import com.yhb.utils.DateUtils;
import lombok.extern.log4j.Log4j;
import lombok.var;
import me.edzh.spring.bootstrap.utils.JSONUtil;
import me.edzh.spring.bootstrap.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Log4j
@Service
public class LeShuaService {
    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static final BigDecimal sMinRate = new BigDecimal("0.54");

    @Autowired
    private MPosMapper mPosMapper;

    @Autowired
    private UserService userService;

    @Autowired
    private LeshuaExecutionFlowMapper leshuaExecutionFlowMapper;

    @Autowired
    @Lazy
    private MPosService mPosService;

    // todo 对回包需要进行比对, 如果费率不对齐, 需要调用接口更改费率.
    // todo 每天晚上1点时需要对前一天22-24点的绑定情况重新查询一次, 避免出现跨天问题. (或者可以通过缓存上次查询end - 1min, 下次查询到触发时间点的方式来保证覆盖. 看哪个好写)
    public List<QueryMerchantResp.Merchant> syncMerchant(Date start, Date end) {
        QueryMerchantResp resp = HttpUtil.request("open_api/query_merchant_info_sync.do", new HashMap<String, String>() {{
            if (start != null) {
                put("startDate", sdf.format(start));
            }
            if (end != null) {
                put("endDate", sdf.format(end));
            }
        }}, QueryMerchantResp.class);

        return resp.getData().getMerchantList();

    }

    public void syncOrders(Date start, Date end) {
        var resp = HttpUtil.request("open_api/query_trans_info_sync.do", new HashMap<String, String>() {{
            if (start != null) {
                put("startDate", sdf.format(start));
            }
            if (end != null) {
                put("endDate", sdf.format(end));
            }
        }}, QueryFlowResp.class);

        if (resp.getResultCode() != 0) {
            log.error("query flow err: " + resp.getResultMsg());
            return;
        }

        for (var flow : resp.getData().getList()) {

            var rate = new BigDecimal(flow.getRate());
            if (rate.compareTo(sMinRate) < 0) {
                log.info(flow.getOrderNo() + "费率低于0.54, 过滤不入库");
                continue; // 低于最低费率, 说明进入鼓励期, 不核算金额
            }
            // 不重复入库
            try {
                if (leshuaExecutionFlowMapper.getExecutionFlowByOrderId(flow.getOrderNo(), DateUtils.getDateString(flow.getOrderTime())) != null) {
                    continue;
                }
            } catch (Throwable ignore) { // 可能出现表不存在
            }


            var u = mPosMapper.getLeshuaBoundByMerchantId(flow.getCoding());
            User user = null;
            if (u != null) {
                user = userService.getUser(u.getUserId());
                if (userService.isPrimeVipInTime(user, flow.getOrderTime())) {
                    flow.setVipType("PRIME");
                }
                flow.setUserId(user.getId());
            }

            // 无主订单也进行入库. 避免数据丢失
            flow.convertAmount();
            var commissionRate = new BigDecimal(flow.getRate()).divide(BigDecimal.valueOf(100));
            flow.setCommission(flow.getAmount().multiply(commissionRate));

            leshuaExecutionFlowMapper.insert(flow, DateUtils.getDateString(flow.getOrderTime()), JSONUtil.toJson(flow));
            if (user != null) {
                mPosService.addUserAmount(user, flow.getAmount());
            }
        }
    }
    public void syncUserFeeRate(List<PosBound> bound, User user) {
        if (user.getVipType() == null) {
            user = userService.getUser(user.getId());
        }

        String rate = getLeshuaRate(user);
        for (var merchant : bound) {
            if (StringUtils.isEmpty(merchant.getMerchantId())) { // 没商户号的直接跳过
                continue;
            }
            HttpUtil.request("open_api/callback_modify_merchant_rate.do", new HashMap<String, String>() {{
                put("merchantId", merchant.getMerchantId());
                put("rateType", rate);
            }}, Map.class);
        }
    }

    public void syncUserFeeRate(List<PosBound> bound) {
        var boundList = bound.parallelStream().collect(Collectors.groupingBy(PosBound::getUserId));
        for (var bounds : boundList.entrySet()) {
            syncUserFeeRate(bounds.getValue(), userService.getUser(bounds.getKey()));
        }
    }

    public void syncUserFeeRate(User user) {
        var bound = mPosMapper.getLeshuaBoundByUserId(user.getId());
        if (bound == null || bound.size() == 0) { // 为空说明这个用户没绑定乐刷
            return;
        }

        syncUserFeeRate(bound, user);
    }

    public List<PosBound> getBounds(String userId) {
        return mPosMapper.getLeshuaBoundByUserId(userId);
    }

    private String getLeshuaRate(User user) {
        switch (user.getVipType()) {
            case ORDINARY:
                return "3";
            case PAYED:
                return "2";
            case PRIME:
                return "1";
        }

        return "3";
    }
}
